import { Words } from './../../../node_modules/ts-jest/node_modules/type-fest/source/words.d';
import { Entity, EntityStatus } from "./Entity";
import { GenericPool, IPoolable } from "./GenericPool";

/**
 * 组件基类
 * 每个component有一个mask值，用于标识组件的类型
 */
export class Component implements IPoolable {

    private _entity: Entity | null = null;


    get entity(): Entity | null {
        return this._entity;
    }

    set entity(entity: Entity | null) {
        this._entity = entity;
    }

    // 回收时的重置
    // 必须实现，否则抛出异常
    onRecycle() {
        throw new Error("Component.onRecycle() must be implemented");
    }

    // 必须实现，否则抛出异常
    onReuse() {
        throw new Error("Component.onReuse() must be implemented");
    }

    get typeName() {
        return Component.getTypeName(this.constructor);
    }

    get typeMask(): bigint {
        return Component.getMask(this.constructor);
    }

    static getTypeName(type: any) {
        return type["ClassName"];
    }

    static getMask(type: any) {
        return type["TypeMask"];
    }

    notifyDataChanged(data: any, oldData: any) {
        if (!this._entity || !this._entity.world || this._entity.status !== EntityStatus.Active) {
            return;
        }
        this._entity.world.viewManager.notifyDataChanged(this, data, oldData);
    }
}

export class ComponentPool extends GenericPool<bigint, Component> {
    constructor() {
        super((component: IPoolable) => (component as Component).typeMask);
    }
}

export class ComponentRegistry {
    private static _registry = new Map<string, any>();
    private static _typeMask = new Map<string, bigint>();
    private static _maskType = new Map<bigint, string>();
    static register(typeName: string, constructor: any) {
        if (this._registry.size === 128) {
            throw new Error("ComponentRegistry.register() too many components");
        }

        if (this._registry.has(typeName)) {
            throw new Error(`Component ${typeName} already registered`);
        }

        constructor["ClassName"] = typeName;
        constructor["TypeMask"] = 1n << BigInt(this._typeMask.size);

        this._registry.set(typeName, constructor);
        this._typeMask.set(typeName, constructor["TypeMask"]);
        this._maskType.set(constructor["TypeMask"], typeName);

        // 日志
        console.log(`Component ${typeName} registered, mask: ${constructor["TypeMask"]}, total: ${this._registry.size}/128`);
    }

    static getByTypeName(typeName: string) {
        return this._registry.get(typeName);
    }

    static getByMask(mask: bigint) {
        const typeName = this._maskType.get(mask);
        if (!typeName) {
            throw new Error(`ComponentRegistry.getByMask() mask ${mask} not found`);
        }
        return this._registry.get(typeName);
    }
}

// export class ComponentFactory {
//     static create(typeName: string): Component | null {
//         const constructor = ComponentRegistry.get(typeName);
//         if (!constructor) {
//             throw new Error(`Component ${typeName} not found`);
//         }
//         return new constructor();
//     }
// }

// 通过一个decorator来注册组件
export function ecs_component(name: string) {
    return function (target: any) {
        ComponentRegistry.register(name, target);
    }
}

